<?php
/**
* 名称：控制器原型类。
* 描述：该类是控制器的原型类，是控制器逻辑的核心构造，定义了控制器的基本契约。
*/
abstract class Controller{
    /**
    * 描述：控制器模式常值。
    */
    const MODE_CLASS='class'; //"类形式"控制器。
    const MODE_EXEC='exec';   //"过程形式"控制器。

    /**
    * 描述：数据库操作对象标量。
    */
    protected static $Database=NULL;

    /**
    * 描述：模板对象标量。
    */
    protected static $Template=NULL;

    /**
    * 数据存储容器标量。
    * @var     int
    * @access private
    */
    protected $Data=array();

    /**
    * 描述：创建模板和数据库操作对象。
    */
    public static function __Initialization(){
        if(is_null(self::$Database)){
            self::$Database=Database::Initialization();
        }
        //~
        if(is_null(self::$Template)){
            self::$Template=Template::Initialization();
            if(self::$Template){
                self::$Template->Assign('_POST',$_POST);
                self::$Template->Assign('_GET',$_GET);
                self::$Template->Assign('_REQUEST',$_REQUEST);
            }
        }
    }

    /**
    * 描述：构建函数，定义了控制器原型的工作原理。
    */
    public function __Construct($method){
        //描述：“参数方法对照表”程序逻辑。
        //逻辑：程序检测如果控制器定义了"MethodTable"属性，将示为采用“参数方法对照“程序逻辑。
        //逻辑：程序如果检测不到”参数对照的方法“，将检测是否定义了默认方法，如果定义了默认方法就执行，否则将转向HTTP404。
        if(property_exists($this,'MethodTable')){
            if(array_key_exists($method,$this->MethodTable)&&method_exists($this,$execMethod=$this->MethodTable[$method])){
                $this->$execMethod();
            }
            else{
                if(array_key_exists('default',$this->MethodTable)&&method_exists($this,$this->MethodTable['default'])){
                    $temp=$this->MethodTable['default'];
                    $this->$temp();
                }
                else{
                    Route::Http416();
                }
            }
        }
        //描述：“参数即方法“程序逻辑。
        //逻辑：程序检测方法名为空时将执行“Main”方法，这是“控制器原型定义默认方法名“。
        //逻辑：程序如果检测没有定义“Main”方法，将发送HTTP404。
        //逻辑：程序要求方法名必须符合“标识符命名规则”，保证程序运行安全。
        //逻辑：程序将拒绝调用以“__”开头的方法，并且将参数值名首字母将大写转为”调用方法名“。
        //逻辑：程序将把包含“_”的参数值以“_”分词合并，并把每一个词的首字母大写来组成“调用方法名”。
        else{
            if($method){
                $isInMethod=(substr($method,0,1)==='__');
                if(TRUE===$isInMethod){
                    Route::Http416();
                }
                else{
                    if(preg_match('/^[_a-zA-Z][a-zA-Z0-9_]*$/',$method)){
                        #处理方法名。
                        if(FALSE===strpos($method,'_')){
                            $method=ucfirst($method);
                        }
                        else{
                            $temp=explode('_',$method);
                            $method=NULL;
                            foreach($temp as $value){
                                $method.=ucfirst($value);
                            }
                        }
                        #如果检测不到方法名。
                        if(method_exists($this,$method)){
                            $this->$method();
                        }
                        else{
                            Route::Http416();
                        }
                    }
                    else{
                        Route::Http416();
                    }
                }
            }
            else{
                if(method_exists($this,'Main')){
                    $this->Main();
                }
                else{
                    Route::Http416();
                }
            }
        }
    }

    /**
    * 描述：载入PHP程式文件。
    * @access public
    * @return void
    */
    public static function Load($filePath){
        include($filePath);
    }
}